﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GmailMetroNotifier.Client.Properties;
using GmailMetroNotifier.Client.Common;

namespace GmailMetroNotifier.Client.UIP
{
    /// <summary>
    /// Implements an <see cref="INotificationProvider"/> that leverages <see cref="MessageBox"/> notifications.
    /// </summary>
    public class DesktopNotificationProvider : INotificationProvider
    {
        /// <summary>
        /// Shows a <see cref="MessageBox"/> on the desktop.
        /// </summary>
        /// <param name="message">The message to show.</param>
        /// <param name="severity">The severity of the message, which also defines the icon to
        /// show in the <see cref="MessageBox"/>.</param>
        public void Notify(string message, NotificationSeverity severity)
        {
            this.Notify(message, severity, null);
        }

        /// <summary>
        /// Shows a <see cref="MessageBox"/> on the desktop.
        /// </summary>
        /// <param name="message">The message to show.</param>
        /// <param name="severity">The severity of the message, which also defines the icon to show in the <see cref="MessageBox"/>.</param>
        /// <param name="resultHandler">The action to be called for handling the notification result.</param>
        public void Notify(string message, NotificationSeverity severity, Action<NotificationResult> resultHandler)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (message.Trim().Length == 0)
            {
                throw new ArgumentException(Resources.EXCEPTION_MSG_ARGUMENT_EXCEPTION, "message");
            }

            MessageBoxButtons buttons = ConvertSeverityToButtons();
            
            MessageBoxIcon icon = ConvertSeverityToIcon(severity);

            DialogResult result = MessageBox.Show(message, Resources.DESKTOP_MSGBOX_DEFAULT_TITLE, buttons, icon);

            if (resultHandler != null)
            {
                resultHandler(ConvertDialogResultToNotificationResult(result));
            }
        }

        private static MessageBoxButtons ConvertSeverityToButtons()
        {
            return MessageBoxButtons.OK;
        }

        private static MessageBoxIcon ConvertSeverityToIcon(NotificationSeverity severity)
        {
            MessageBoxIcon icon = MessageBoxIcon.None;

            switch (severity)
            {
                case NotificationSeverity.Information:
                    icon = MessageBoxIcon.Information;
                    break;

                case NotificationSeverity.Warning:
                    icon = MessageBoxIcon.Warning;
                    break;

                case NotificationSeverity.Error:
                    icon = MessageBoxIcon.Error;
                    break;
            }

            return icon;
        }

        private static NotificationResult ConvertDialogResultToNotificationResult(DialogResult dialogResult)
        {
            NotificationResult notificationResult = NotificationResult.None;

            switch (dialogResult)
            {
                case DialogResult.None:
                    notificationResult = NotificationResult.None;
                    break;

                case DialogResult.Yes:
                case DialogResult.OK:
                    notificationResult = NotificationResult.OK;
                    break;

                case DialogResult.No:
                case DialogResult.Cancel:
                    notificationResult = NotificationResult.Cancel;
                    break;
                
                case DialogResult.Abort:
                    notificationResult = NotificationResult.Abort;
                    break;
                
                case DialogResult.Ignore:
                    notificationResult = NotificationResult.Ignore;
                    break;

                case DialogResult.Retry:
                    notificationResult = NotificationResult.Retry;
                    break;
            }

            return notificationResult;
        }
    }
}
